#pragma once

#include <iostream>
#include <queue>
#include "Mutex.hpp"
#include "Connection.hpp"
#include "IntAddr.hpp"

using namespace MyMutex;
namespace Equeue
{
    class event_queue
    {
    private:
        event_queue()
        {
        }
        event_queue(const event_queue &) = delete;
        event_queue &operator()(const event_queue &) = delete;
        ~event_queue()
        {
        }
        void Enqueuehelper(std::pair<int,InetAddr>& Con)
        {
            _equeue.push(Con);
        }
        std::pair<int,InetAddr>& Pophelper()
        {
            std::pair<int,InetAddr>& cur = _equeue.front();
            _equeue.pop();
            return cur;
        }
    public:
        static event_queue *GetInStance()
        {
            if (_ins == nullptr)
            {
                LockGuard nowlock(_lock);
                if (_ins == nullptr)
                {
                    _ins = new event_queue();
                }
            }
            return _ins;
        }

        void Enqueue(std::vector<std::pair<int,InetAddr>>* eq)
        {
            LockGuard nowlock(_lock);
            while(!eq->empty())
            {
                Enqueuehelper(eq->back());
                eq->pop_back();
            }
        }

        void PopAll(std::vector<std::pair<int,InetAddr>>* sockfds)
        {
            LockGuard nowlock(_lock);
            while(!_equeue.empty())
            {
                sockfds->push_back(Pophelper());
            }
        }

    private:
        std::queue<std::pair<int,InetAddr>> _equeue;

        static Mutex _lock;
        static event_queue *_ins;
    };

    event_queue *event_queue::_ins = nullptr;

    Mutex event_queue::_lock;
}